package com.example.bob.controller;

import com.example.bob.common.AppVariable;
import com.example.bob.common.ResultAjax;
import com.example.bob.model.ArticleInfo;
import com.example.bob.model.UserInfo;
import com.example.bob.model.vo.UserInfoVO;
import com.example.bob.service.ArticleService;
import com.example.bob.service.UserService;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpSession;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.HashMap;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

@Controller
@ResponseBody
@RequestMapping("/art")
public class ArticleController {


    @Resource //
    private ArticleService articleService;
    private static final int _DESC_LENGTH = 120; // 文章简介的长度
    @Resource //线程池
    private ThreadPoolTaskExecutor taskExecutor;
    @Resource
    private UserService userService;

    // 我的博客列表！（没有分页功能）
    @RequestMapping("/mylist")
    public ResultAjax getMyList(HttpServletRequest request) throws ExecutionException, InterruptedException {
        HttpSession session = request.getSession(false);
        // 从会话中获取userInfo
        UserInfo userInfo = (UserInfo) session.getAttribute(AppVariable.SESSION_USERINFO_KEY);
        if (userInfo != null) {
            //截取文章的前120个字符作为文章简介！
            FutureTask<List<ArticleInfo>> listFutureTask = new FutureTask<>(() -> {
                List<ArticleInfo> list = articleService.getListByUser(userInfo.getId());
                if (list != null && list.size() > 0) {
                    // 并行处理 list 集合
                    list.stream().parallel().forEach((art) -> {
                        if (art.getContent().length() > _DESC_LENGTH) {
                            art.setContent(art.getContent().substring(0, _DESC_LENGTH));
                        }
                    });
                }
                return list;
            });
            taskExecutor.submit(listFutureTask);

            FutureTask<Integer> artCountTask = new FutureTask<>(() -> {
                return articleService.artCount(userInfo.getId());
            });
            taskExecutor.submit(artCountTask);

            List<ArticleInfo> list = listFutureTask.get();
            int artCount = artCountTask.get(); // 等待任务（线程池）执行完成

            HashMap<String,Object> data = new HashMap<>();
            data.put("list",list);
            data.put("user",userInfo);
            data.put("artcount",artCount);
            return ResultAjax.succ(data);

        } else {
            return ResultAjax.fail(-1,"获取失败！");
        }
    }


    //查询网站所有博客！
    @RequestMapping("/getlistbypage")
    //pindex:第几页
    //psize:每一页的大小
    public ResultAjax getListByPage(Integer pindex,Integer psize,HttpServletRequest request){
        int check=0;
        HttpSession session = request.getSession(false);
        if (session != null && session.getAttribute(AppVariable.SESSION_USERINFO_KEY) != null) {
            check=1;
        }

        Integer offset = psize*(pindex-1);
        List<ArticleInfo> list = articleService.getListByPage(psize,offset);
        if (list != null && list.size() > 0) {
            // 并行处理 list 集合
            list.stream().parallel().forEach((art) -> {
                if (art.getContent().length() > _DESC_LENGTH) {
                    art.setContent(art.getContent().substring(0, _DESC_LENGTH));
                }
            });
        }
        //计算一共有多少页数：
        int count = articleService.count();
        int size= count/psize;
        if(count%size!=0) size++;
        HashMap<String, Object> map = new HashMap<>();
        map.put("check",check);
        map.put("list", list);
        map.put("size", size);
        return ResultAjax.succ(map);
    }


    /*
    * 添加博客
    * 前端过来的数据只有标题和正文
    * 后端使用ArticleInfo对象来接收*/

    @RequestMapping("/add")
    public ResultAjax add(ArticleInfo articleInfo,HttpServletRequest request){
        //校验参数

        //添加文章到数据库
        /*
        * 我要添加一篇文章，还需要传一个作者id,文章表中的uid*/

        HttpSession session = request.getSession(false);
        UserInfo userInfo = (UserInfo)session.getAttribute(AppVariable.SESSION_USERINFO_KEY);

        if(userInfo==null) return ResultAjax.fail(-2,"未登录，请先登录");
        articleInfo.setUid(userInfo.getId());

        // 执行添加操作：
        int ret = articleService.add(articleInfo);
        //返回响应
        return ResultAjax.succ(ret);
    }
    //删除功能
    //前端给我aid,后端使用ArticleInfo对象来接收

    //前端传递过来的是aid,但是articleInfo对象没有aid属性，所以没有注入成功
    @RequestMapping("/del")
    public ResultAjax del(Integer aid,HttpServletRequest request){
        int ret = 0;
        ArticleInfo articleInfo = new ArticleInfo();
        articleInfo.setId(aid);
        //删除一篇文章需要文章id,uid (身份校验，自能自己删除自己的文章),
        HttpSession session = request.getSession(false);
        UserInfo userInfo = (UserInfo)session.getAttribute(AppVariable.SESSION_USERINFO_KEY);

        if(userInfo==null) return ResultAjax.fail(-2,"未登录，请先登录");
        articleInfo.setUid(userInfo.getId());

        //删除操作
        ret = articleService.del(articleInfo);
        return ResultAjax.succ(ret);
    }



    //查看博客详情页，传递一个aid够不够？够了，所有人都可以查看，没有身份验证

    // 真奇葩，首页竟然没有个人信息！
    //查看文章详情的时候由个人信息，和文章详情并发查询！
    //所以说:接收什么样的参数以及返回什么是前后端统一的！
    //返回用户对象和文章对象的集合！
    @RequestMapping("/detail")
    //我明白了，我这样写参数是存在问题的，我的需求是没有登陆，也可以查看博客池，我的参数设置有HttpServletRequest
    //这时已经登录之后才能够传递cookie,所以不能能有这个参数！
    public ResultAjax detail(Integer aid,HttpServletRequest request) throws ExecutionException, InterruptedException {
        //校验参数
        if(aid<=0) return ResultAjax.fail(-3,"非法参数！");

        int check=0;
        HttpSession session = request.getSession(false);
        if (session != null && session.getAttribute(AppVariable.SESSION_USERINFO_KEY) != null) {
            check=1;
        }
        //查询文章详情
        ArticleInfo articleInfo = articleService.detail(aid);
        //查询用户信息
        FutureTask<UserInfoVO> userInfoTask = new FutureTask<>(() -> {
            return userService.getUserById(articleInfo.getUid());
        });
        taskExecutor.submit(userInfoTask);
        //查询用户文章总数量
        FutureTask<Integer> artCountTask = new FutureTask<>(() -> {
            return articleService.artCount(articleInfo.getUid());
        });
        taskExecutor.submit(artCountTask);


        //组装数据
        UserInfoVO userinfoVO = userInfoTask.get();
        int artCount = artCountTask.get(); // 等待任务（线程池）执行完成
        userinfoVO.setArtCount(artCount);

        HashMap<String,Object> data = new HashMap<>();
        data.put("user",userinfoVO);
        data.put("art",articleInfo);
        data.put("check",check);
        return ResultAjax.succ(data);
    }


    //更新文章
    //1,回显文章(POSt)
    //2,编辑文章（前端内置md编辑器）
    //3,更新文章请求(POST)

    @RequestMapping("/update_init") // 回显文章！
    public ResultAjax updateInit(Integer aid,HttpServletRequest request){

        HttpSession session = request.getSession(false);
        if(session==null) return ResultAjax.fail(-2,"未登录，请先登录");
        UserInfo userInfo = (UserInfo)session.getAttribute(AppVariable.SESSION_USERINFO_KEY);
        if(userInfo==null) return ResultAjax.fail(-2,"未登录，请先登录");
        ArticleInfo articleInfo  = articleService.detail(aid);
        return ResultAjax.succ(articleInfo);

    }


    //居然是更新文章 传递一个文章对象！以及cookie来校验身份
    @RequestMapping("/update")
    public ResultAjax updata(ArticleInfo articleInfo,HttpServletRequest request){
        //校验参数
        if(articleInfo==null)
            ResultAjax.fail(-1,"非法参数");
        HttpSession session = request.getSession(false);
        if(session==null) return ResultAjax.fail(-2,"未登录，请先登录");
        UserInfo userInfo = (UserInfo)session.getAttribute(AppVariable.SESSION_USERINFO_KEY);
        if(userInfo==null) return ResultAjax.fail(-2,"未登录，请先登录");
        //更新数据库
        System.out.println("旧"+articleInfo.getUid());
        articleInfo.setUid(userInfo.getId());
        System.out.println("新"+articleInfo.getUid());


        int ret = articleService.updata(articleInfo);
        //返回响应
        return ResultAjax.succ(ret);
    }

    //查询文章的阅读量，这个在数据库中是有的
    //这个需要什么身份验证吗？不需要的1，因为大家都可以查看文章详情！
    @RequestMapping("/increment_recount")
    public ResultAjax incrementRCount(Integer aid){
        int recount = articleService.getReCount(aid);
        articleService.setReCount(recount+1,aid);
        return ResultAjax.succ(recount);
    }

}
